#include "nv.h"
#include "ui_GUI.h"
#include <QtGui/QtGui>

using namespace std;

/*//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//                          Inicializacion
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
NV::NV(QWidget *parent) : QWidget(parent), ui(new Ui::NV)
{
    ui->setupUi(this);
    this->showFullScreen();
    client = new nv_network();
    session = new cryptography();
    conex_ing_usuario();
}

NV::~NV()
{
    delete ui;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//                          Pantalla de ingreso de usuario
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void NV::conex_ing_usuario(){
    ui->widget_pin->hide();
    ui->widget_ballot->hide();
    ui->widget_ing->hide();
    ui->widget_config->hide();

    ui->widget_ing->show();
    ui->lineEdit_ing_carne->clear();

    if(QFile::exists("e*")||QFile::exists("d*")){
        QString cmd("rm ");
        if(QFile::exists("e*"))
            cmd.append("e*");
        if(QFile::exists("d*"))
            cmd.append("d*");
        system(cmd.toAscii().data());
    }

    connect(ui->toolButton_ing_aceptar,SIGNAL(clicked()),this,SLOT(conex_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_Apagar,SIGNAL(clicked()),this,SLOT(close()),Qt::UniqueConnection);
    connect(ui->lineEdit_ing_carne,SIGNAL(returnPressed()),this,SLOT(conex_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_configuracion,SIGNAL(clicked()),this,SLOT(conex_config()),Qt::UniqueConnection);
}

/*///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//                          Pantalla de ingreso del pin
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/

void NV::conex_pin(){
    if(ui->lineEdit_ing_carne->text().isEmpty()){
        return;
    }
    ui->widget_ing->hide();
    ui->widget_pin->show();
    QString num="0123456789";
    int pointer = session->Random.GenerateWord32(0,num.size()-1);
    ui->toolButton_pinup1->setText(num.at(pointer));
    num.remove(pointer,1);

    pointer = session->Random.GenerateWord32(0,num.size()-1);
    ui->toolButton_pinup2->setText(num.at(pointer));
    num.remove(pointer,1);

    pointer = session->Random.GenerateWord32(0,num.size()-1);
    ui->toolButton_pinup3->setText(num.at(pointer));
    num.remove(pointer,1);

    pointer = session->Random.GenerateWord32(0,num.size()-1);
    ui->toolButton_pinup4->setText(num.at(pointer));
    num.remove(pointer,1);

    pointer = session->Random.GenerateWord32(0,num.size()-1);
    ui->toolButton_pinup5->setText(num.at(pointer));
    num.remove(pointer,1);

    pointer = session->Random.GenerateWord32(0,num.size()-1);
    ui->toolButton_pindown1->setText(num.at(pointer));
    num.remove(pointer,1);

    pointer = session->Random.GenerateWord32(0,num.size()-1);
    ui->toolButton_pindown2->setText(num.at(pointer));
    num.remove(pointer,1);

    pointer = session->Random.GenerateWord32(0,num.size()-1);
    ui->toolButton_pindown3->setText(num.at(pointer));
    num.remove(pointer,1);

    pointer = session->Random.GenerateWord32(0,num.size()-1);
    ui->toolButton_pindown4->setText(num.at(pointer));
    num.remove(pointer,1);

    pointer = session->Random.GenerateWord32(0,num.size()-1);
    ui->toolButton_pindown5->setText(num.at(pointer));
    num.remove(pointer,1);

    borrar_pin();

    connect(ui->toolButton_pinup1,SIGNAL(clicked()),this,SLOT(up1_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_pinup2,SIGNAL(clicked()),this,SLOT(up2_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_pinup3,SIGNAL(clicked()),this,SLOT(up3_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_pinup4,SIGNAL(clicked()),this,SLOT(up4_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_pinup5,SIGNAL(clicked()),this,SLOT(up5_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_pindown1,SIGNAL(clicked()),this,SLOT(down1_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_pindown2,SIGNAL(clicked()),this,SLOT(down2_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_pindown3,SIGNAL(clicked()),this,SLOT(down3_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_pindown4,SIGNAL(clicked()),this,SLOT(down4_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_pindown5,SIGNAL(clicked()),this,SLOT(down5_pin()),Qt::UniqueConnection);

    connect(ui->toolButton_pin_borrar,SIGNAL(clicked()),this,SLOT(borrar_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_pin_aceptar,SIGNAL(clicked()),this,SLOT(aceptar_pin()),Qt::UniqueConnection);
    connect(ui->toolButton_pin_regresar,SIGNAL(clicked()),this,SLOT(conex_ing_usuario()),Qt::UniqueConnection);
}

void NV::borrar_pin(){
    ui->label_pin->clear();
}

void NV::aceptar_pin(){
    if(ui->label_pin->text().size()<4){
        show_msg("Ha ingresado un pin invalido!","Vuelva a ingresar su pin","",QMessageBox::Critical);
        ui->label_pin->clear();
        return;}

    QString m1,m5,B,H;

    if(!client->connect2Server()){
        show_msg("No se ha establecido la conexion con el servidor","","",QMessageBox::Critical);
        ui->widget_pin->hide();
        conex_ing_usuario();
        return;
    }

// Envia indicacion de que la conexion es para el envio de M1(hay que recibir varios mensajes antes de poder enviar M1)
    client->send_msg(QString::number(nv_network::M1msg));

 // Obtiene las llaves publicas del  Ballot Generator, el Key Generator y Counter respectivamente
    if(!client->read_msg(client->msg_RX)){
        return;
    }

    session->Hex2Key(client->msg_RX,"eb");

    if(!client->read_msg(client->msg_RX)){
        return;
    }

    session->Hex2Key(client->msg_RX,"ek");

    if(!client->read_msg(client->msg_RX)){
        return;
    }

    session->Hex2Key(client->msg_RX,"ec");

// Crea las llaves para comunicar con el Key Generator y el Ballot Generator
    session->create_key("s"); // Llave para comunicarse con el BG
    session->create_key("v"); // Llave para comunicarse con el KG y el counter

// Genera M1 y lo envia
    QString PVID1(session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text()));
    session->M1(PVID1,m1);

    client->send_msg(m1);

// Recibe Verificacion
    if(!client->read_msg(client->msg_RX)){

        return;
    }

    if(client->msg_RX==QString::number(client->invalidM1)){
        show_msg("No ha sido autenticado satisfactoriamente!",
                "Vuelva a intentarlo y si el problema persiste busque asistencia tecnica",
                "Esto puede ser ocasionado por un error en el ingreso del pin o a que su usuario ya realizo la votacion de esta propuesta",
                QMessageBox::Critical);
        ui->widget_pin->hide();
        conex_ing_usuario();
        return;
    }


// Recibe M5
    if(!client->read_msg(m5)){
        return;
    }

    if(!session->M5(m5,B)){
        return;
    }

// Calcula H(B,es) y lo chequea en BGBB
    H = session->Hash(B,"es");
    client->send_msg(H);

    if(!client->read_msg(client->msg_RX)){
        return;
    }

    if(client->msg_RX.toInt()==client->wrongHash){
        return;
    }

// Calcula H(ev,ez) y lo chequea en el KGBB
    H = session->HashKeys("ev","ez");
    client->send_msg(H);

    if(!client->read_msg(client->msg_RX)){
        return;
    }

    if(client->msg_RX.toInt()==client->wrongHash){
        return;
    }

    client->client->disconnectFromHost();
    show_Prop(B);

}

void NV::up1_pin(){
    if(ui->label_pin->text().size()<4)
        ui->label_pin->setText(ui->label_pin->text().append(ui->toolButton_pinup1->text()));
}

void NV::up2_pin(){
    if(ui->label_pin->text().size()<4)
        ui->label_pin->setText(ui->label_pin->text().append(ui->toolButton_pinup2->text()));
}

void NV::up3_pin(){
    if(ui->label_pin->text().size()<4)
        ui->label_pin->setText(ui->label_pin->text().append(ui->toolButton_pinup3->text()));
}

void NV::up4_pin(){
    if(ui->label_pin->text().size()<4)
        ui->label_pin->setText(ui->label_pin->text().append(ui->toolButton_pinup4->text()));
}

void NV::up5_pin(){
    if(ui->label_pin->text().size()<4)
        ui->label_pin->setText(ui->label_pin->text().append(ui->toolButton_pinup5->text()));
}

void NV::down1_pin(){
    if(ui->label_pin->text().size()<4)
        ui->label_pin->setText(ui->label_pin->text().append(ui->toolButton_pindown1->text()));
}

void NV::down2_pin(){
    if(ui->label_pin->text().size()<4)
        ui->label_pin->setText(ui->label_pin->text().append(ui->toolButton_pindown2->text()));
}

void NV::down3_pin(){
    if(ui->label_pin->text().size()<4)
        ui->label_pin->setText(ui->label_pin->text().append(ui->toolButton_pindown3->text()));
}

void NV::down4_pin(){
    if(ui->label_pin->text().size()<4)
        ui->label_pin->setText(ui->label_pin->text().append(ui->toolButton_pindown4->text()));
}

void NV::down5_pin(){
    if(ui->label_pin->text().size()<4)
        ui->label_pin->setText(ui->label_pin->text().append(ui->toolButton_pindown5->text()));
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//                          Pantalla de votacion
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void NV::show_Prop(QString &Ballot){
    ui->widget_pin->hide();
    ui->widget_ballot->show();

    ui->toolButton_vote_der->hide();
    ui->toolButton_vote_izq->hide();
    ui->toolButton_vote_opc1->hide();
    ui->toolButton_vote_opc2->hide();
    ui->toolButton_vote_opc3->hide();
    ui->toolButton_vote_opc4->hide();
    ui->toolButton_vote_opc5->hide();

    QString buffer = "Propuesta ";
    QString aux;
    buffer.append(shift_String(Ballot));
    aux=shift_String(Ballot);
    if(!aux.isEmpty()){
        buffer.append("-");
        buffer.append(aux);
    }
    ui->label_num_prop->setText(buffer);
    buffer = multi_line(shift_String(Ballot),57);
    ui->label_desc_prop->setText(buffer);
    ui->label_desc_prop->setToolTip(buffer);

    aux=shift_String(Ballot);

    switch(aux.toInt()){
    case 1:{
        ui->label_desc_prop->setMaximumHeight(120);
        default_ballot(Ballot);
        ui->label_desc_prop->setText(buffer);
        ui->label_desc_prop->setToolTip(buffer);

        int space=272-ui->label_num_prop->size().height()-ui->label_desc_prop->size().height()-ui->toolButton_vote_izq->size().height();

        ui->verticalLayout_etiq->setSpacing(space*0.1);
        ui->verticalLayout_main->setSpacing(space*0.25);
        ui->verticalLayout_opc->setSpacing(space*0.25);
        ui->verticalSpacer_up->changeSize(1,space*0.1);
        ui->verticalSpacer_down->changeSize(1,space*0.30);
        ui->label_desc_prop->setAlignment(Qt::AlignHCenter|Qt::AlignTop);
        }
        break;
    case 2:{
        ui->label_desc_prop->setMaximumHeight(80);
        opc2_ballot(Ballot);
        int space=272-ui->label_num_prop->size().height()-ui->label_desc_prop->size().height()-ui->toolButton_vote_opc1->size().height()-ui->toolButton_vote_opc2->size().height();

        ui->verticalLayout_etiq->setSpacing(space*0.1);
        ui->verticalLayout_main->setSpacing(space*0.25);
//        ui->verticalLayout_opc->setSpacing(space*0.25);
        ui->verticalSpacer_up->changeSize(1,space*0.1);
        ui->verticalSpacer_down->changeSize(1,space*0.30);
        }
        break;
    case 3:{
        ui->label_desc_prop->setMaximumHeight(60);
        opc3_ballot(Ballot);
        int space=272-ui->label_num_prop->size().height()-ui->label_desc_prop->size().height()-ui->toolButton_vote_opc1->size().height()-ui->toolButton_vote_opc2->size().height()-ui->toolButton_vote_opc3->size().height();

        ui->verticalLayout_etiq->setSpacing(space*0.1);
        ui->verticalLayout_main->setSpacing(space*0.25);
        ui->verticalLayout_opc->setSpacing(space*0.25);
        ui->verticalSpacer_up->changeSize(1,space*0.1);
        ui->verticalSpacer_down->changeSize(1,space*0.30);
        }
        break;
    case 4:{
        ui->label_desc_prop->setMaximumHeight(40);
        opc4_ballot(Ballot);
        int space=272-ui->label_num_prop->size().height()-ui->label_desc_prop->size().height()-ui->toolButton_vote_opc1->size().height()-ui->toolButton_vote_opc2->size().height()-ui->toolButton_vote_opc3->size().height()-ui->toolButton_vote_opc4->size().height();

        ui->verticalLayout_etiq->setSpacing(space*0.1);
        ui->verticalLayout_main->setSpacing(space*0.25);
        ui->verticalLayout_opc->setSpacing(space*0.25);
        ui->verticalSpacer_up->changeSize(1,space*0.1);
        ui->verticalSpacer_down->changeSize(1,space*0.30);
        }
        break;
    case 5:{
        ui->label_desc_prop->setMaximumHeight(40);
        opc5_ballot(Ballot);

        int space=272-ui->label_num_prop->size().height()-ui->label_desc_prop->size().height()-ui->toolButton_vote_opc1->size().height()-ui->toolButton_vote_opc2->size().height()-ui->toolButton_vote_opc3->size().height()-ui->toolButton_vote_opc4->size().height()-ui->toolButton_vote_opc5->size().height();

        ui->verticalLayout_etiq->setSpacing(space*0.1);
        ui->verticalLayout_main->setSpacing(space*0.25);
        ui->verticalLayout_opc->setSpacing(space*0.25);
        ui->verticalSpacer_up->changeSize(1,space*0.1);
        ui->verticalSpacer_down->changeSize(1,space*0.30);
        }
        break;
    }
    if(!Ballot.isEmpty()){
        aux=ui->label_num_prop->text();
        aux.replace("Propuesta",Ballot);
        ui->label_num_prop->setText(aux);
    }
    return;
}

void NV::default_ballot(QString &Ballot){
    ui->toolButton_vote_izq->setText(shift_String(Ballot));
    ui->toolButton_vote_der->setText(shift_String(Ballot));
    ui->verticalLayout_etiq->setSpacing(20);
    ui->verticalLayout_main->setSpacing(40);
    ui->toolButton_vote_der->show();
    ui->toolButton_vote_izq->show();

    connect(ui->toolButton_vote_izq,SIGNAL(clicked()),this,SLOT(izquierda()),Qt::UniqueConnection);
    connect(ui->toolButton_vote_der,SIGNAL(clicked()),this,SLOT(derecha()),Qt::UniqueConnection);
}

void NV::opc2_ballot(QString &Ballot){
    int n = 50*4;
    QString buffer = multi_line(shift_String(Ballot),n/4);

    if(buffer.size()<n){
        ui->toolButton_vote_opc1->setText(buffer);
        ui->toolButton_vote_opc1->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc1->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc1->setToolTip(buffer);
    }

    buffer = multi_line(shift_String(Ballot),n/4);

    if(buffer.size()<n){
        ui->toolButton_vote_opc2->setText(buffer);
        ui->toolButton_vote_opc2->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc2->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc2->setToolTip(buffer);
    }

    ui->toolButton_vote_opc1->show();
    ui->toolButton_vote_opc2->show();
    ui->toolButton_vote_opc1->setMinimumHeight(ui->toolButton_vote_opc1->size().height());
    ui->toolButton_vote_opc2->setMinimumHeight(ui->toolButton_vote_opc2->size().height());

    connect(ui->toolButton_vote_opc1,SIGNAL(clicked()),this,SLOT(opc1()),Qt::UniqueConnection);
    connect(ui->toolButton_vote_opc2,SIGNAL(clicked()),this,SLOT(opc2()),Qt::UniqueConnection);
}

void NV::opc3_ballot(QString &Ballot){
    int n = 50*3;
    QString buffer = multi_line(shift_String(Ballot),n/3);

    if(buffer.size()<n){
        ui->toolButton_vote_opc1->setText(buffer);
        ui->toolButton_vote_opc1->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc1->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc1->setToolTip(buffer);
    }

    buffer = multi_line(shift_String(Ballot),n/3);
    if(buffer.size()<n){
        ui->toolButton_vote_opc2->setText(buffer);
        ui->toolButton_vote_opc2->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc2->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc2->setToolTip(buffer);
    }

    buffer = multi_line(shift_String(Ballot),n/3);
    if(buffer.size()<n){
        ui->toolButton_vote_opc3->setText(buffer);
        ui->toolButton_vote_opc3->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc3->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc3->setToolTip(buffer);
    }

    ui->toolButton_vote_opc1->show();
    ui->toolButton_vote_opc2->show();
    ui->toolButton_vote_opc3->show();
    ui->toolButton_vote_opc1->setMinimumHeight(ui->toolButton_vote_opc1->size().height());
    ui->toolButton_vote_opc2->setMinimumHeight(ui->toolButton_vote_opc2->size().height());
    ui->toolButton_vote_opc3->setMinimumHeight(ui->toolButton_vote_opc3->size().height());

    connect(ui->toolButton_vote_opc1,SIGNAL(clicked()),this,SLOT(opc1()),Qt::UniqueConnection);
    connect(ui->toolButton_vote_opc2,SIGNAL(clicked()),this,SLOT(opc2()),Qt::UniqueConnection);
    connect(ui->toolButton_vote_opc3,SIGNAL(clicked()),this,SLOT(opc3()),Qt::UniqueConnection);
}

void NV::opc4_ballot(QString &Ballot){
    int n = 50*2;
    QString buffer = multi_line(shift_String(Ballot),n/2);

    if(buffer.size()<n){
        ui->toolButton_vote_opc1->setText(buffer);
        ui->toolButton_vote_opc1->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc1->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc1->setToolTip(buffer);
    }

    buffer = multi_line(shift_String(Ballot),n/2);
    if(buffer.size()<n){
        ui->toolButton_vote_opc2->setText(buffer);
        ui->toolButton_vote_opc2->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc2->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc2->setToolTip(buffer);
    }

    buffer = multi_line(shift_String(Ballot),n/2);
    if(buffer.size()<n){
        ui->toolButton_vote_opc3->setText(buffer);
        ui->toolButton_vote_opc3->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc3->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc3->setToolTip(buffer);
    }

    buffer = multi_line(shift_String(Ballot),n/2);
    if(buffer.size()<n){
        ui->toolButton_vote_opc4->setText(buffer);
        ui->toolButton_vote_opc4->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc4->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc4->setToolTip(buffer);
    }
    ui->toolButton_vote_opc1->show();
    ui->toolButton_vote_opc2->show();
    ui->toolButton_vote_opc3->show();
    ui->toolButton_vote_opc4->show();
    ui->toolButton_vote_opc1->setMinimumHeight(ui->toolButton_vote_opc1->size().height());
    ui->toolButton_vote_opc2->setMinimumHeight(ui->toolButton_vote_opc2->size().height());
    ui->toolButton_vote_opc3->setMinimumHeight(ui->toolButton_vote_opc3->size().height());
    ui->toolButton_vote_opc4->setMinimumHeight(ui->toolButton_vote_opc4->size().height());

    connect(ui->toolButton_vote_opc1,SIGNAL(clicked()),this,SLOT(opc1()),Qt::UniqueConnection);
    connect(ui->toolButton_vote_opc2,SIGNAL(clicked()),this,SLOT(opc2()),Qt::UniqueConnection);
    connect(ui->toolButton_vote_opc3,SIGNAL(clicked()),this,SLOT(opc3()),Qt::UniqueConnection);
    connect(ui->toolButton_vote_opc4,SIGNAL(clicked()),this,SLOT(opc4()),Qt::UniqueConnection);
}

void NV::opc5_ballot(QString &Ballot){
    int n = 50*2;
    QString buffer = multi_line(shift_String(Ballot),n/2);

    if(buffer.size()<n){
        ui->toolButton_vote_opc1->setText(buffer);
        ui->toolButton_vote_opc1->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc1->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc1->setToolTip(buffer);
    }

    buffer = multi_line(shift_String(Ballot),n/2);
    if(buffer.size()<n){
        ui->toolButton_vote_opc2->setText(buffer);
        ui->toolButton_vote_opc2->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc2->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc2->setToolTip(buffer);
    }

    buffer = multi_line(shift_String(Ballot),n/2);
    if(buffer.size()<n){
        ui->toolButton_vote_opc3->setText(buffer);
        ui->toolButton_vote_opc3->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc3->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc3->setToolTip(buffer);
    }

    buffer = multi_line(shift_String(Ballot),n/2);
    if(buffer.size()<n){
        ui->toolButton_vote_opc4->setText(buffer);
        ui->toolButton_vote_opc4->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc4->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc4->setToolTip(buffer);
    }

    buffer = multi_line(shift_String(Ballot),n/2);
    if(buffer.size()<n){
        ui->toolButton_vote_opc5->setText(buffer);
        ui->toolButton_vote_opc5->setToolTip(buffer);
    }
    else{
        ui->toolButton_vote_opc5->setText(QString(buffer).remove(n,buffer.size()));
        ui->toolButton_vote_opc5->setToolTip(buffer);
    }
    ui->toolButton_vote_opc1->show();
    ui->toolButton_vote_opc2->show();
    ui->toolButton_vote_opc3->show();
    ui->toolButton_vote_opc4->show();
    ui->toolButton_vote_opc5->show();
    ui->toolButton_vote_opc1->setMinimumHeight(ui->toolButton_vote_opc1->size().height());
    ui->toolButton_vote_opc2->setMinimumHeight(ui->toolButton_vote_opc2->size().height());
    ui->toolButton_vote_opc3->setMinimumHeight(ui->toolButton_vote_opc3->size().height());
    ui->toolButton_vote_opc4->setMinimumHeight(ui->toolButton_vote_opc4->size().height());
    ui->toolButton_vote_opc5->setMinimumHeight(ui->toolButton_vote_opc5->size().height());


    connect(ui->toolButton_vote_opc1,SIGNAL(clicked()),this,SLOT(opc1()),Qt::UniqueConnection);
    connect(ui->toolButton_vote_opc2,SIGNAL(clicked()),this,SLOT(opc2()),Qt::UniqueConnection);
    connect(ui->toolButton_vote_opc3,SIGNAL(clicked()),this,SLOT(opc3()),Qt::UniqueConnection);
    connect(ui->toolButton_vote_opc4,SIGNAL(clicked()),this,SLOT(opc4()),Qt::UniqueConnection);
    connect(ui->toolButton_vote_opc5,SIGNAL(clicked()),this,SLOT(opc5()),Qt::UniqueConnection);
}

void NV::derecha(){
    switch(show_msg(ui->toolButton_vote_der->text(),
                    "Confirma que desea enviar su voto?","",
                    QMessageBox::Information,QMessageBox::No|QMessageBox::Yes)){
        case QMessageBox::No:
            return;
        case QMessageBox::Yes:
            break;
        }

    QString PVID1 =session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text());
    QString PVID2 =session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text());

    if(vote_Cast(QString::number(2),PVID1,PVID2)){
        QString info ="PVID1 = ";
        info.append(PVID1);
        info.append("\nPVID2 = ").append(PVID2);
        info.append("\nNumero de verificacion = ").append(Vote_hash);

        show_msg("Su voto ha sido enviado!",info);
        conex_ing_usuario();
    }
    else{
        show_msg("No se ha podido enviar su voto!","","",QMessageBox::Critical);
        conex_ing_usuario();
    }
}

void NV::izquierda(){
    switch(show_msg(ui->toolButton_vote_izq->text(),
                    "Confirma que desea enviar su voto?","",
                    QMessageBox::Information,QMessageBox::No|QMessageBox::Yes)){
        case QMessageBox::No:
            return;
        case QMessageBox::Yes:
            break;
        }
    QString PVID1 =session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text());
    QString PVID2 =session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text());

    if(vote_Cast(QString::number(1),PVID1,PVID2)){
        QString info ="PVID1 = ";
        info.append(PVID1);
        info.append("\nPVID2 = ").append(PVID2);
        info.append("\nNumero de verificacion = ").append(Vote_hash);

        show_msg("Su voto ha sido enviado!",info);
        conex_ing_usuario();
        }
    else{
        show_msg("No se ha podido enviar su voto!","","",QMessageBox::Critical);
        conex_ing_usuario();
    }
}

void NV::opc1(){
    /*if(vote_Cast(QString::number(1),
                 session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text()),
                 session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text())))*/
    switch(show_msg(ui->toolButton_vote_opc1->text(),
                    "Confirma que desea enviar su voto?","",
                    QMessageBox::Information,QMessageBox::No|QMessageBox::Yes)){
        case QMessageBox::No:
            return;
        case QMessageBox::Yes:
            break;
        }

    QString PVID1 =session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text());
    QString PVID2 =session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text());

    if(vote_Cast(QString::number(1),PVID1,PVID2)){
        QString info ="PVID1 = ";
        info.append(PVID1);
        info.append("\nPVID2 = ").append(PVID2);
        info.append("\nNumero de verificacion = ").append(Vote_hash);

        show_msg("Su voto ha sido enviado!",info);
        conex_ing_usuario();
    }
    else{
        show_msg("No se ha podido enviar su voto!","","",QMessageBox::Critical);
        conex_ing_usuario();
    }
}

void NV::opc2(){
/*    if(vote_Cast(QString::number(2),
                 session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text()),
                 session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text())))*/
    switch(show_msg(ui->toolButton_vote_opc2->text(),
                    "Confirma que desea enviar su voto?","",
                    QMessageBox::Information,QMessageBox::No|QMessageBox::Yes)){
        case QMessageBox::No:
            return;
        case QMessageBox::Yes:
            break;
        }

    QString PVID1 =session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text());
    QString PVID2 =session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text());

    if(vote_Cast(QString::number(2),PVID1,PVID2)){
        QString info ="PVID1 = ";
        info.append(PVID1);
        info.append("\nPVID2 = ").append(PVID2);
        info.append("\nNumero de verificacion = ").append(Vote_hash);

        show_msg("Su voto ha sido enviado!",info);
        conex_ing_usuario();
    }
    else{
        show_msg("No se ha podido enviar su voto!","","",QMessageBox::Critical);
        conex_ing_usuario();
    }
}

void NV::opc3(){
    /*if(vote_Cast(QString::number(3),
                 session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text()),
                 session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text())))*/
    switch(show_msg(ui->toolButton_vote_opc3->text(),
                    "Confirma que desea enviar su voto?","",
                    QMessageBox::Information,QMessageBox::No|QMessageBox::Yes)){
        case QMessageBox::No:
            return;
        case QMessageBox::Yes:
            break;
        }

    QString PVID1 =session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text());
    QString PVID2 =session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text());

    if(vote_Cast(QString::number(3),PVID1,PVID2)){
        QString info ="PVID1 = ";
        info.append(PVID1);
        info.append("\nPVID2 = ").append(PVID2);
        info.append("\nNumero de verificacion = ").append(Vote_hash);

        show_msg("Su voto ha sido enviado!",info);
        conex_ing_usuario();
    }
    else{
        show_msg("No se ha podido enviar su voto!","","",QMessageBox::Critical);
        conex_ing_usuario();
    }
}

void NV::opc4(){
/*    if(vote_Cast(QString::number(4),
                 session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text()),
                 session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text())))*/
    switch(show_msg(ui->toolButton_vote_opc4->text(),
                    "Confirma que desea enviar su voto?","",
                    QMessageBox::Information,QMessageBox::No|QMessageBox::Yes)){
        case QMessageBox::No:
            return;
        case QMessageBox::Yes:
            break;
        }

    QString PVID1 =session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text());
    QString PVID2 =session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text());

    if(vote_Cast(QString::number(4),PVID1,PVID2)){
        QString info ="PVID1 = ";
        info.append(PVID1);
        info.append("\nPVID2 = ").append(PVID2);
        info.append("\nNumero de verificacion = ").append(Vote_hash);

        show_msg("Su voto ha sido enviado!",info);
        conex_ing_usuario();
    }
    else{
        show_msg("No se ha podido enviar su voto!","","",QMessageBox::Critical);
        conex_ing_usuario();
    }
}

void NV::opc5(){
/*    if(vote_Cast(QString::number(5),
                 session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text()),
                 session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text())))*/

    switch(show_msg(ui->toolButton_vote_opc5->text(),
                    "Confirma que desea enviar su voto?","",
                    QMessageBox::Information,QMessageBox::No|QMessageBox::Yes)){
        case QMessageBox::No:
            return;
        case QMessageBox::Yes:
            break;
        }

    QString PVID1 =session->PVID_generation(ui->lineEdit_ing_carne->text(),ui->label_pin->text());
    QString PVID2 =session->PVID_generation(ui->label_pin->text(),ui->lineEdit_ing_carne->text());

    if(vote_Cast(QString::number(5),PVID1,PVID2)){
        QString info ="PVID1 = ";
        info.append(PVID1);
        info.append("\nPVID2 = ").append(PVID2);
        info.append("\nNumero de verificacion = ").append(Vote_hash);

        show_msg("Su voto ha sido enviado!",info);
        conex_ing_usuario();
    }
    else{
        show_msg("No se ha podido enviar su voto!","","",QMessageBox::Critical);
        conex_ing_usuario();
    }
}

QString NV::shift_String(QString &msg){
    QString buffer;

    int shift = msg.indexOf("&&");

    for(int j=0;j<shift; j++){
        buffer.append(msg.at(j));
    }

    msg.remove(0,shift);
    msg.remove(0,2); // borra &&
    return buffer;
}

bool NV::vote_Cast(QString vote, QString PVID1, QString PVID2){

    QString Ec,Ez,V,ev,m6;

// Genera m6
    V=QString::number(vote.size());
    V.append("&&").append(vote).append(PVID2);

    Ez=session->encryptMsg(V,"ez");

    Vote_hash=session->Hash(Ez);

    Ec=QString::number(PVID1.size());
    Ec.append("&&").append(QString::number(Ez.size())).append("&&");

    if(!session->Key2Hex("ev",ev)){
        return false;
    }

    Ec.append(PVID1).append(Ez).append(ev);

    m6=session->encryptMsg(Ec,"ec");

// Conexion con el servidor
    if(!client->connect2Server()){
        show_msg("No se ha podido establecer la conexion con el servidor","","",QMessageBox::Critical);
        return false;
    }

// Envia indicacion de que la conexion es para el envio de M6
    client->send_msg(QString::number(nv_network::M6msg));
    client->send_msg(m6);

// Espera la confirmacion de recibido por parte del servidor (OJO VIENE ENCRIPTADO)
    if(!client->read_msg(client->msg_RX)){
        return false;
    }

    if(client->msg_RX.toInt()==client->invalidVote){
        return false;
    }

    return true;

}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//                                      Pantalla de configuracion
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void NV::conex_config(){
    ui->widget_config->show();
    ui->widget_ing->hide();
    ui->comboBox_interfaces->clear();
    ui->comboBox_interfaces->insertItems(0,client->show_interfaces());

    QSettings settings("AIR", "SVE");
    if(settings.contains("Interface")){
        ui->comboBox_interfaces->setCurrentIndex(ui->comboBox_interfaces->findText(settings.value("Interface").toString()));
        ui->lineEdit_config_IP_local->setText(settings.value("IP local").toString());
        ui->lineEdit_config_pin->setText(settings.value("pin").toString());
        ui->lineEdit_config_IP_server->setText(settings.value("IP server").toString());
        ui->spinBox_config_Port->setValue(settings.value("Port").toInt());
        ui->lineEdit_config_pin->setStyleSheet("QLineEdit{background-color: white;color: blue; border: 2px inset rgb(213, 213,213); border-radius: 3px; selection-background-color: rgb(236, 232, 209);}    QLineEdit:hover, QLineEdit:focus{border-color: rgb(255, 170, 0)} QLineEdit:disabled {background-color: rgb(226, 220, 255);color: rgb(62, 62, 0);}");

    }
    else{
        ui->comboBox_interfaces->setCurrentIndex(-1);
        ui->lineEdit_config_IP_local->clear();
        ui->lineEdit_config_pin->clear();
        ui->lineEdit_config_IP_server->clear();
        ui->spinBox_config_Port->setValue(23000);
        ui->lineEdit_config_pin->setStyleSheet("QLineEdit{background-color: white;color: red; border: 2px inset rgb(213, 213,213); border-radius: 3px; selection-background-color: rgb(236, 232, 209);}    QLineEdit:hover, QLineEdit:focus{border-color: rgb(255, 170, 0)} QLineEdit:disabled {background-color: rgb(226, 220, 255);color: rgb(62, 62, 0);}");
    }

    connect(ui->button_config_aceptar,SIGNAL(clicked()),this,SLOT(config_aceptar()),Qt::UniqueConnection);
    connect(ui->button_config_cancelar,SIGNAL(clicked()),this,SLOT(config_cancelar()),Qt::UniqueConnection);
    connect(ui->comboBox_interfaces,SIGNAL(currentIndexChanged(int)),this,SLOT(config_interface()),Qt::UniqueConnection);
    connect(ui->button_config_verificar_pin,SIGNAL(clicked()),this,SLOT(config_check_pin()),Qt::UniqueConnection);
    connect(ui->lineEdit_config_pin,SIGNAL(returnPressed()),this,SLOT(config_check_pin()),Qt::UniqueConnection);
}

void NV::config_cancelar(){
    ui->widget_config->hide();
    ui->widget_ing->show();
    disconnect(ui->comboBox_interfaces,SIGNAL(currentIndexChanged(int)),this,SLOT(config_interface()));
}

void NV::config_aceptar(){

    QSettings settings("AIR", "SVE");
    settings.setValue("Interface",ui->comboBox_interfaces->currentText());
    settings.setValue("IP local",ui->lineEdit_config_IP_local->text().toAscii());
    settings.setValue("pin",ui->lineEdit_config_pin->text().toAscii());
    settings.setValue("IP server",ui->lineEdit_config_IP_server->text().toAscii());
    settings.setValue("Port",ui->spinBox_config_Port->text().toAscii());

    ui->widget_config->hide();
    ui->widget_ing->show();
    disconnect(ui->comboBox_interfaces,SIGNAL(currentIndexChanged(int)),this,SLOT(config_interface()));
}

void NV::config_interface(){
    ui->lineEdit_config_IP_local->setText(client->interface_IP(ui->comboBox_interfaces->currentText()));
}

void NV::config_check_pin(){
    QSettings settings("AIR", "SVE");
    settings.setValue("IP local",ui->lineEdit_config_IP_local->text().toAscii());
    settings.setValue("pin",ui->lineEdit_config_pin->text().toAscii());

    if(client->connect2Server())
        ui->lineEdit_config_pin->setStyleSheet("QLineEdit{background-color: white;color: blue; border: 2px inset rgb(213, 213,213); border-radius: 3px; selection-background-color: rgb(236, 232, 209);}    QLineEdit:hover, QLineEdit:focus{border-color: rgb(255, 170, 0)} QLineEdit:disabled {background-color: rgb(226, 220, 255);color: rgb(62, 62, 0);}");
    else{
        ui->lineEdit_config_pin->setStyleSheet("QLineEdit{background-color: white;color: red; border: 2px inset rgb(213, 213,213); border-radius: 3px; selection-background-color: rgb(236, 232, 209);}    QLineEdit:hover, QLineEdit:focus{border-color: rgb(255, 170, 0)} QLineEdit:disabled {background-color: rgb(226, 220, 255);color: rgb(62, 62, 0);}");
        show_msg("No se ha registrado el nodo correctamente!","Vuelva a ingresar el codigo de seguridad","",QMessageBox::Critical);
        }

    client->client->disconnectFromHost();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int NV::show_msg(QString message, QString info, QString detail, QMessageBox::Icon icono, QMessageBox::StandardButtons buttons){
    QMessageBox message1(this);
    message1.setStyleSheet("QAbstractButton{background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(157, 246, 227, 255), stop:1 rgba(168, 168, 168, 255)); border-top-color: rgb(233, 248, 241); border-left-color: rgb(233, 248, 241); border-bottom-color: rgb(81, 120, 107); border-right-color: rgb(81, 120, 107); border-style: outset; border-width: 2px; padding: 3px; border-radius: 15px; min-height:20 px; min-width:80 px; color: black} QAbstractButton:pressed{background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(97, 186, 167, 255), stop:1 rgba(148, 148, 148, 255)); color: rgb(85, 0, 0); border-style: inset; border-top-color: rgb(81, 120, 107); border-left-color: rgb(81, 120, 107); border-bottom-color: rgb(233, 248, 241); border-right-color: rgb(233, 248, 241);} QLabel{color: rgb(255,255,100); background-color: rgba(170, 255, 255, 0)} QDialog{background-color: rgb(132, 150, 255);}");
    message1.setWindowModality(Qt::ApplicationModal);
    message1.setText(message.prepend("<b>").append("</b>"));
    message1.setInformativeText(info);
    message1.setDetailedText(detail);
    message1.setIcon(icono);
    message1.setStandardButtons(buttons);
    return message1.exec();
}

QString NV::multi_line(QString data, int width){
    QString aux,line;

    if(data.count(" ")==0){
        aux=data;

        for(int i=0;i<data.size();i+=width+2){
            aux.insert(i+width,"\n");
        }
    }
    else{
        QStringList list;
        list = data.split(QRegExp("\\s+"));

        for(int i = 0;(i<list.size())|(i==1000);i++){
            if(list.at(i).size() < width && (line.size() + list.at(i).size()) < width){
                line.append(list.at(i)).append(" ");
            }
            else{
                aux.append(line).append("\n");
                line.clear();
                line = list.at(i);
                line.append(" ");
            }
        }

        if(!line.isEmpty()){
            aux.append(line);
            line.clear();
        }
        aux.append("\n");
    }
    return aux;
}
